<template>
  <div class="schedule-container">
    <div class="schedule-left">
      <CalendarViewSelect
        v-model="currentDate"
        :legend-items="legendItems"
        :dot-calculator="scheduleDotCalculator"
        @month-change="getMonthData"
        @change="handleDayClick"
      />
    </div>

    <div class="schedule-right">
      <ContentWrap class="search-wrap">
        <!-- 搜索工作栏 -->
        <el-form
          class="-mb-15px"
          :model="queryParams"
          ref="queryFormRef"
          :inline="true"
          label-width="68px"
        >
          <el-form-item label="日程标题" prop="title">
            <el-input
              v-model="queryParams.title"
              placeholder="请输入日程标题"
              clearable
              @keyup.enter="handleQuery"
              class="!w-240px"
            />
          </el-form-item>
          <el-form-item label="状态" prop="status">
            <el-select
              v-model="queryParams.status"
              placeholder="请选择状态"
              clearable
              class="!w-160px"
            >
              <el-option
                v-for="dict in getIntDictOptions(DICT_TYPE.COMMON_STATUS)"
                :key="dict.value"
                :label="dict.label"
                :value="dict.value"
              />
            </el-select>
          </el-form-item>

          <el-form-item>
            <el-button @click="handleQuery"
              ><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button
            >
            <el-button @click="resetQuery"
              ><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button
            >
            <el-button
              type="primary"
              plain
              @click="openForm('create')"
              v-hasPermi="['school:schedule:create']"
            >
              <Icon icon="ep:plus" class="mr-5px" /> 新增
            </el-button>
            <el-button
              type="success"
              plain
              @click="handleExport"
              :loading="exportLoading"
              v-hasPermi="['school:schedule:export']"
            >
              <Icon icon="ep:download" class="mr-5px" /> 导出
            </el-button>
          </el-form-item>
        </el-form>
      </ContentWrap>

      <!-- 卡片列表 -->
      <div class="card-list">
        <template v-if="filteredList.length">
          <div v-for="(item, index) in filteredList" :key="index" class="schedule-card">
            <div class=""
              ><div class="inline-block w-90px text-right text-18px text-#333">日程标题：</div
              >{{ item.title }}</div
            >
            <div class=""
              ><div class="inline-block w-90px text-right">详细内容：</div
              >{{ item.description }}</div
            >
            <div class=""
              ><div class="inline-block w-90px text-right">开始时间：</div
              >{{ formatDate(item.startTime) }}</div
            >
            <div class=""
              ><div class="inline-block w-90px text-right">结束时间：</div
              >{{ formatDate(item.endTime) }}</div
            >
            <div class=""
              ><div class="inline-block w-90px text-right">创建时间：</div
              >{{ formatDate(item.createTime) }}</div
            >
            <div class="" :data="item.statusObj = getDictObj(DICT_TYPE.COMMON_STATUS, item.status)"
              ><div class="inline-block w-90px text-right">状态：</div
              ><span :class="[{ 'text-#14D10A': item.statusObj.value === '0' }]">{{
                item.statusObj.label
              }}</span></div
            >

            <div class="flex justify-end items-baseline mt--9px">
              <el-button
                link
                type="primary"
                @click="openForm('update', item.id)"
                v-hasPermi="['school:schedule:update']"
                >编辑</el-button
              >
              <el-button
                class="!m-l-6px"
                link
                type="danger"
                @click="handleDelete(item.id)"
                v-hasPermi="['school:schedule:delete']"
                >删除</el-button
              >
            </div>
          </div>
        </template>
        <template v-else>
          <el-empty v-if="!loading" description="暂无日程" />
        </template>
      </div>
    </div>
  </div>

  <!-- 表单弹窗：添加/修改 -->
  <ScheduleForm ref="formRef" @success="handleFormSuccess" />
</template>

<script setup lang="ts">
import { getIntDictOptions, getDictObj, DICT_TYPE } from '@/utils/dict'
import download from '@/utils/download'
import { ScheduleApi, ScheduleVO } from '@/api/school/schedule'
import ScheduleForm from './ScheduleForm.vue'
import { formatDate, beginOfDay, endOfDay } from '@/utils/formatTime'
import { isNumber } from '@/utils/is'
import { LegendItem, CalendarDot } from '@/components/CalendarViewSelect/index.vue'
/** 日程 列表 */
defineOptions({ name: 'SchoolSchedule' })

const { query } = useRoute()
const message = useMessage() // 消息弹窗
const { t } = useI18n() // 国际化

const currentDate: any = ref(new Date()) // 当前选中的日期
const selectedDate = ref(formatDate(new Date(), 'YYYY-MM-DD')) // 选中的日期字符串
const monthData = ref<Record<string, number>>({}) // 月份数据，记录每天的日程数量

// 定义图例项
const legendItems: LegendItem[] = [
  {
    style: { backgroundColor: 'var(--el-color-primary)', width: '6px' },
    text: '单日程事项'
  },
  {
    style: { backgroundColor: 'var(--el-color-primary)', width: '12px' },
    text: '多日程事项'
  }
]
// 定义日程点计算器
const scheduleDotCalculator = (day: string): CalendarDot[] => {
  const key = day.replace(/-/g, '')
  const scheduleCount = monthData.value[key] || 0
  const dots: CalendarDot[] = []

  if (scheduleCount === 1) {
    // 单日程事项
    dots.push(legendItems[0])
  } else if (scheduleCount > 1) {
    // 多日程事项，比单日程宽一倍
    dots.push(legendItems[1])
  }

  return dots
}

const loading = ref(true) // 列表的加载中
const list = ref<ScheduleVO[]>([]) // 列表的数据
const queryParams = reactive({
  title: undefined,
  status: undefined,
  day: formatDate(new Date(), 'YYYY-MM-DD') // 添加day参数用于按日期查询
})
const queryFormRef = ref() // 搜索的表单
const exportLoading = ref(false) // 导出的加载中
// 筛选列表
const filteredList: any = computed(() => {
  // 先根据搜索条件过滤
  let result = list.value

  // 根据主题搜索
  if (queryParams.title) {
    result = result.filter((item) => item.title.includes(queryParams.title!))
  }
  if (isNumber(queryParams.status)) {
    result = result.filter((item) => item.status === queryParams.status)
  }

  return result
})
/** 查询列表 */
const getList = async () => {
  loading.value = true
  try {
    // 使用getScheduleByDay获取当天日程列表，无分页
    // 接口入参也是YYYYMM格式
    const day = formatDate(new Date(queryParams.day), 'YYYYMMDD')
    const data = await ScheduleApi.getScheduleByDay(day)
    list.value = data || []
  } finally {
    loading.value = false
  }
}

/** 获取指定月份的日程数据 */
const getMonthData = async (month: string) => {
  try {
    // ScheduleApi.getScheduleByMonth返回的已经是一个对象类型，无需转换
    // 入参日期格式YYYYMM
    const data = await ScheduleApi.getScheduleByMonth(month)
    monthData.value = {}
    // 返回日期（key）对应value是当天日程数量
    Object.keys(data).forEach((key) => {
      monthData.value[key] = data[key]
    })
  } catch (error) {
    console.error('获取月份日程数据失败:', error)
  }
}

/** 获取指定日期的日程 */
const getDaySchedule = async (day: string) => {
  // 更新查询参数中的日期
  queryParams.day = day
  // 查询该日期的日程
  await getList()
}

/** 处理日期选择 */
const handleDaySelect = (value: Date) => {
  const dateStr = formatDate(value, 'YYYY-MM-DD')
  selectedDate.value = dateStr
  getDaySchedule(dateStr)
}

/** 处理日期点击 */
const handleDayClick = (data: any) => {
  const date = new Date(data.day)
  handleDaySelect(date)
}

/** 搜索按钮操作 */
const handleQuery = () => {
  getList()
}

/** 重置按钮操作 */
const resetQuery = () => {
  queryFormRef.value.resetFields()
  handleQuery()
}

/** 添加/修改操作 */
const formRef = ref()
const openForm = (type: string, id?: number) => {
  formRef.value.open(type, id, {
    startTime: beginOfDay(currentDate.value).getTime(),
    endTime: endOfDay(currentDate.value).getTime()
  })
}

/** 删除按钮操作 */
const handleDelete = async (id: number) => {
  try {
    // 删除的二次确认
    await message.delConfirm()
    // 发起删除
    await ScheduleApi.deleteSchedule(id)
    message.success(t('common.delSuccess'))
    // 刷新列表
    await getList()
    // 重新获取当前月份数据以更新日历上的点
    const month = formatDate(currentDate.value, 'YYYYMM')
    await getMonthData(month)
  } catch {}
}

/** 导出按钮操作 */
const handleExport = async () => {
  try {
    // 导出的二次确认
    await message.exportConfirm()
    // 发起导出
    exportLoading.value = true
    const data = await ScheduleApi.exportSchedule(queryParams)
    download.excel(data, '日程.xls')
  } catch {
  } finally {
    exportLoading.value = false
  }
}

/** 表单操作成功回调 */
const handleFormSuccess = async () => {
  // 重新获取当前月份数据以更新日历上的点
  const month = formatDate(currentDate.value, 'YYYYMM')
  await getMonthData(month)
  // 刷新列表
  await getList()
}

watch(
  () => query.dayDate,
  (dayDate) => {
    const isUpdate = dayDate === currentDate.value
    if (dayDate) {
      currentDate.value = dayDate
    }
    if (isUpdate || !dayDate) {
      // 获取当前月份数据
      const month = formatDate(currentDate.value, 'YYYYMM')
      getMonthData(month)
      // 获取当前日期的会议预约
      handleDayClick({ day: currentDate.value })
    }
  },
  {
    immediate: true
  }
)
</script>

<style lang="scss" scoped>
.schedule-container {
  display: flex;
  column-gap: 20px;
  height: $content-height;
}

.schedule-left {
  width: 350px;
  padding: 15px;
  background-color: #fff;
  flex-shrink: 0;
}

.schedule-right {
  flex: 1;
  display: flex;
  flex-direction: column;
  overflow: hidden;

  .search-wrap,
  .table-wrap {
    background-color: #fff;
  }

  .card-list {
    display: flex;
    flex-direction: column;
    gap: 10px;
    height: calc($content-height - 65px);
    overflow-y: auto; /* 启用垂直滚动 */

    .schedule-card {
      position: relative;
      padding: 15px 15px 9px;
      color: #666;
      background-color: var(--card-bg-color);
      border-left: 2.1px solid var(--card-border-color);
      border-radius: 4px;

      &:nth-child(6n + 1) {
        --card-bg-color: #fff2f2;
        --card-border-color: #ff6969;
      }

      &:nth-child(6n + 2) {
        --card-bg-color: #fff6ed;
        --card-border-color: #ffa978;
      }

      &:nth-child(6n + 3) {
        --card-bg-color: #f2fff2;
        --card-border-color: #6eff6e;
      }

      &:nth-child(6n + 4) {
        --card-bg-color: #f0ffff;
        --card-border-color: #82fffd;
      }

      &:nth-child(6n + 5) {
        --card-bg-color: #edf3ff;
        --card-border-color: #8f9eff;
      }

      &:nth-child(6n + 6) {
        --card-bg-color: #fff0ff;
        --card-border-color: #ff54fc;
      }
    }
  }
}
</style>
